package config.center.core.zoo;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.nio.charset.StandardCharsets;

/**
 * zookeeper operate manager
 * TODO: should be replaced by special zk operator
 * @author gaowenhao
 * @since 2021/9/16 21:19
 */
public class ZookeeperManager {

    private final CuratorFramework curatorFramework;

    public ZookeeperManager(CuratorFramework curatorFramework) {
        this.curatorFramework = curatorFramework;
    }

    public CuratorFramework getCuratorFramework() {
        return this.curatorFramework;
    }

    /**
     * transform a config key to a zk path
     * @param key
     * @return
     */
    public String keyToPath(String key) {
        return "/" + key.replaceAll("\\.", "/");
    }

    /**
     * create a zk node recursively with specified path, node mode and content
     *
     * @param path
     * @param mode
     * @param content
     * @return
     * @throws Exception
     */
    public String create(String path, CreateMode mode, String content) throws Exception {
        return this.create(path, mode, content.getBytes(StandardCharsets.UTF_8));
    }


    /**
     * create a zk node recursively with specified path, node mode and content
     *
     * @param path
     * @param mode
     * @param content
     * @return
     */
    public String create(String path, CreateMode mode, byte[] content) throws Exception {
        return curatorFramework.create().creatingParentsIfNeeded().withMode(mode).forPath(path, content);
    }


    /**
     * check node is exist
     *
     * @param path
     * @return
     * @throws Exception
     */
    public boolean exist(String path) throws Exception {
        return this.curatorFramework.checkExists().forPath(path) != null;
    }


    /**
     * get data from special zk node
     *
     * @param path
     * @return
     * @throws Exception
     */
    public String getData(String path) throws Exception {
        return this.exist(path) ? new String(this.curatorFramework.getData().forPath(path)) : null;
    }


    /**
     * delete a single zk node hardly
     *
     * @param path
     * @throws Exception
     */
    public void delete(String path) throws Exception {
        this.curatorFramework.delete().guaranteed().forPath(path);
    }

    /**
     * delete zk node with it's child nodes recursively
     *
     * @param path
     * @throws Exception
     */
    public void deleteRecursively(String path) throws Exception {
        this.curatorFramework.delete().guaranteed().deletingChildrenIfNeeded().forPath(path);
    }


    /**
     * update node data
     *
     * @param path
     * @param newContent
     * @return
     * @throws Exception
     */
    public Stat update(String path, String newContent) throws Exception {
        return this.update(path, newContent.getBytes(StandardCharsets.UTF_8));
    }


    /**
     * update node data
     *
     * @param path
     * @param newContent
     * @return
     * @throws Exception
     */
    public Stat update(String path, byte[] newContent) throws Exception {
        return this.curatorFramework.setData().forPath(path, newContent);
    }


}
